package main

import (
	"bufio"
	"fmt"
	"gopkg.in/urfave/cli.v1"
	"os"
	"sort"
)
var (
	app = cli.NewApp()//生成最基本的命令行程序实例app
)

var inputReader *bufio.Reader //具有reader方法的*bufio.Reader指针
var input string
var err error
func main() {


	//运行并接受输入参数，如果存在错误打印标准错误输出并退出执行（非0）
	if err := app.Run(os.Args); err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}
	inputReader = bufio.NewReader(os.Stdin) //将标准输入与读取器绑定，读取内容，返回带缓存reader对象
	fmt.Println("Please enter some input: ")
	input, err = inputReader.ReadString('\n') //缓存对象到换行符为止
	if err == nil {
		fmt.Printf("The input was: %s\n", input)  //读取顺利则打印读取内容
	}
}

func init() {
	var language string
    //创建命令行实例
	//app := cli.NewApp()
	//配置命令行公共属性，名字，使用说明，版本
	app.Name = "GoFlag"
	app.Usage = "flag test "
	app.Version = "1.0.0"
	//每一个具体int和string flag实例（-x调用），包括调用名字name以及逗号后的简写，默认值value，使用说明usage，变量值保存传递Destination
	app.Flags = []cli.Flag {
		cli.IntFlag {
			Name: "port, p",
			Value: 8080,
			Usage: "listening port",
		},
		cli.StringFlag {
			Name: "lang, l",
			Value: "Chinese",
			Usage: "read from `FILE`",
			Destination: &language,
		},
	}
	//每一个具体命令调用（x调用），调用名字name，调用别名Aliases，使用说明Usage，分组目录Category，关联函数action，子命令Subcommands
	app.Commands = []cli.Command {
		{
			Name: "add",
			Aliases: []string{"a"},
			Usage: "calc 1+1",
			Category: "arithmetic", //实现分组显示，同一值同一组
			Action: func(c *cli.Context) error {
				fmt.Println("1 + 1 = ", 1 + 1)
				return nil
			},
		},
		{
			Name: "sub",
			Aliases: []string{"s"},
			Usage: "calc 5-3",
			Category: "arithmetic",
			Action: func(c *cli.Context) error {
				fmt.Println("5 - 3 = ", 5 - 3)
				return nil
			},
		},
		{
			Name: "db",
			Usage: "database operations",
			Category: "database",
			Subcommands: []cli.Command {
				{
					Name: "insert",
					Usage: "insert data",
					Action: func(c *cli.Context) error {
						fmt.Println("insert subcommand")
						return nil
					},
				},
				{
					Name: "delete",
					Usage: "delete data",
					Action: func(c *cli.Context) error {
						fmt.Println("delete subcommand")
						return nil
					},
				},
			},
		},
	}
	//命令行入口函数即什么都不输入或者只输入flag
	app.Action = func(c *cli.Context) error {
		fmt.Println("BOOM!")
		fmt.Println(c.String("lang"), c.Int("port"))
		fmt.Println(language)

		// if c.Int("port") == 8000 {
		// 	return cli.NewExitError("invalid port", 88)
		// }

		return nil
	}
	//command命令执行前操作
	app.Before = func(c *cli.Context) error {
		fmt.Println("app Before")
		return nil
	}
	//command命令执行后操作
	app.After = func(c *cli.Context) error {
		fmt.Println("app After")
		return nil
	}
    //flag按照字典顺序排列，而非声明顺序
	sort.Sort(cli.FlagsByName(app.Flags))
    //打印帮助信息
	cli.HelpFlag = cli.BoolFlag {
		Name: "help, h",
		Usage: "Help!Help!",
	}
    //打印版本信息
	cli.VersionFlag = cli.BoolFlag {
		Name: "print-version, v",
		Usage: "print version",
	}

	/*err := app.Run(os.Args)
	if err != nil {
		log.Fatal(err)
	}*/
}
